﻿namespace NKernel.Core.Impl
{
    using System;
    using System.Collections.Generic;

    using log4net;

    /// <summary>
    /// Abstract implementation of the IKernel
    /// </summary>
    internal abstract class AbstractKernel : IKernel
    {
        #region Fields

        /// <summary>
        /// String array of the components with priority status
        /// For example, components that have higher priority for initialisation and starting, while the 
        /// </summary>
        protected string[] PriorityComponents;

        /// <summary>
        /// Reference to the class responsible for managing the state of each component
        /// </summary>
        private readonly ComponentLifeCycleHandler componentLifeCycleHandler;

        /// <summary>
        /// Logging instance
        /// </summary>
        private readonly ILog logger = LogManager.GetLogger(typeof (AbstractKernel));

        #endregion Fields

        #region Constructors

        protected AbstractKernel()
        {
            componentLifeCycleHandler = new ComponentLifeCycleHandler();
        }

        #endregion Constructors

        #region Properties

        internal ComponentLifeCycleHandler ComponentLifeCycleHandler
        {
            get { return componentLifeCycleHandler; }
        }

        #endregion Properties

        #region Methods

        public abstract KernelResult Cleanup();

        public abstract IList<IComponentObject> GetComponents();

        public abstract T GetInstance<T>();

        public abstract KernelResult Init();

        public void InitPriorityList(string[] components)
        {
            if (components == null || components.Length == 0)
            {
                PriorityComponents = new string[] { };
            }
            else
            {
                PriorityComponents = components;
            }

            if (logger.IsDebugEnabled)
            {
                logger.DebugFormat("Priority component: {0}", String.Join(", ", PriorityComponents));
            }
        }

        public abstract KernelResult Load(string[] componentLocations);

        public abstract KernelResult Load();

        public abstract KernelResult Manage();

        public abstract KernelResult Manage(string[] componentLocations);

        public abstract KernelResult Start();

        public abstract KernelResult Stop();

        #endregion Methods
    }
}